package com.coocaa.x.service.liteupgrade;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import com.coocaa.x.framework.app.CoocaaService;
import com.coocaa.x.framework.utils.Android;
import com.coocaa.x.framework.utils.LogUtils;
import com.coocaa.x.service.liteupgrade.aidl.ILiteUpgradeService;
import com.coocaa.x.service.liteupgrade.aidl.UpgradeInfo;
import com.coocaa.x.service.liteupgrade.aidl.UpgradeParams;

import java.io.File;


public class LiteUpgradeService extends CoocaaService {

    private static class MyStub extends ILiteUpgradeService.Stub implements LiteUpgradeDownloader.LiteUpgradeDownloaderListener {
        private LiteUpgradeKernel kernel = null;
        private LiteUpgradeDownloader downloader = null;
        private Context mContext = null;
        private String save_path = null;
        private String update_file_path = null, update_temp_file_path = null;

        public MyStub(Context context) {
            mContext = context;
            downloader = new LiteUpgradeDownloader();
            downloader.setListener(this);
            kernel = loadKernel();
            if (kernel != null) {
                kernel.setDownloader(downloader);
                save_path = kernel.getSavePath();

                File file = new File(save_path);
                file.setReadable(true, false);

                update_file_path = save_path + "/" + LiteUpgradeDownloader.UPDATE_FILE;
                update_temp_file_path = save_path + "/" + LiteUpgradeDownloader.UPDATE_TEMP_FILE;
            }
        }

        private LiteUpgradeKernel loadKernel() {
            Object obj = Android.getMetaData(mContext, mContext.getPackageName(), LiteUpgradeKernel.META_NAME);
            if (obj == null)
                return null;
            try {
                return (LiteUpgradeKernel) Class.forName((String) obj).newInstance();
            } catch (Exception e) {
            }
            return null;
        }


        @Override
        public synchronized String exec(String cmd, UpgradeParams params) throws RemoteException {
            if (kernel == null)
                throw new RemoteException("Are you ok??  No upgradekernel has been loaded!!!!");
            return kernel.exec(cmd, params);
        }

        @Override
        public synchronized UpgradeInfo checkUpgrade(UpgradeParams params) throws RemoteException {
            kernel.prepare(params);
            UpgradeInfo info = kernel.getUpgradeInfo();
            if (info.hasUpgrade)
                performDownload(info);
            else
                kernel.onUpdateFileNotExist();
            return info;
        }

        @Override
        public void whoAmI() {
            LogUtils.d("wai", "<<LiteUpgradeService>> who am i??  " + mContext.getPackageName());
        }

        private int getCurrentVersionCode() {
            int versionCode = -1;
            try {
                versionCode = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionCode;
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
                LogUtils.e("upgrade", "getCurrentVersionCode " + e.getMessage());
            }
            return versionCode;
        }

        private int getDownloadedUpdateApkVersionCode() {
            if (new File(update_temp_file_path).exists())
                return -1;//正在下載
            if (new File(update_file_path).exists()) {
                try {
                    PackageManager pm = mContext.getPackageManager();
                    PackageInfo info = pm.getPackageArchiveInfo(update_file_path, PackageManager.GET_ACTIVITIES);
                    return info.versionCode;
                } catch (Exception e) {
                }
            }
            //沒有下載過
            return -2;
        }

        private void performDownload(UpgradeInfo info) {
            int current_vc = getCurrentVersionCode();
            int downloaded_vc = getDownloadedUpdateApkVersionCode();
            LogUtils.i("upgrade", "performDownload current_vc:" + current_vc + "  downloaded_vc:" + downloaded_vc + "  info.ver:" + info.versionCode);
            LogUtils.i("upgrade", "performDownload update_file_path:" + update_file_path);
            if (downloaded_vc == -1) {
                kernel.onUpdateFileNotExist();
                downloader.start(new File(update_file_path), kernel.getDownloadUrl(), info.md5);
            } else if (downloaded_vc == -2) {
                kernel.onUpdateFileNotExist();
                if (current_vc < info.versionCode)
                    downloader.start(new File(update_file_path), kernel.getDownloadUrl(), info.md5);
            } else {
                if (current_vc >= downloaded_vc) {
                    File file = new File(update_temp_file_path);
                    if (file.exists())
                        file.delete();
                    file = new File(update_file_path);
                    if (file.exists())
                        file.delete();
                    kernel.onUpdateFileNotExist();
                    if (current_vc < info.versionCode)
                        downloader.start(new File(update_file_path), kernel.getDownloadUrl(), info.md5);
                } else if (downloaded_vc > current_vc && downloaded_vc >= info.versionCode) {
                    kernel.onUpdateFilePrepared(update_file_path);
                } else {
                    File file = new File(update_temp_file_path);
                    if (file.exists())
                        file.delete();
                    file = new File(update_file_path);
                    if (file.exists())
                        file.delete();
                    kernel.onUpdateFileNotExist();
                    if (current_vc < info.versionCode)
                        downloader.start(new File(update_file_path), kernel.getDownloadUrl(), info.md5);
                }
            }
        }

        @Override
        public void onStart() {
            kernel.onStart();
        }

        @Override
        public void onProgress(int percent, long downloaded_length, long file_length) {
            kernel.onProgress(percent, downloaded_length, file_length);
        }

        @Override
        public void onCancel() {
            kernel.onCancel();
        }

        @Override
        public void onError(String e) {
            kernel.onError(e);
        }

        @Override
        public void onSuccess(File f) {
            kernel.onSuccess(f);
            kernel.onUpdateFilePrepared(f.getAbsolutePath());
        }
    }

    private MyStub stub = null;

    @Override
    public void onCreate() {
        super.onCreate();

        stub = new MyStub(this);
    }

    @Override
    public IBinder onBind(Intent intent) {
        return stub;
    }
}
